import math
import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
'''
    Graphics View中有三个有效的坐标系统：
    Item坐标系，
    场景坐标系，
    视图坐标系。
    
    QGraphicsScene 称为图形场景。
    QGraphicsView 称为图形窗口
    QGraphicsScene图形窗口 都有自己的无视觉外观，它只管理项目。
    QGraphicsView图形视图 加载 部件可视化的场景。 
    ou first create a subclass of QGraphicsItem , 
    and then start by implementing its two pure virtual public functions: 
    boundingRect() : returns an estimate of the area painted by the item, and 
    paint() : which implements the actual painting. 
'''

'''
QtCore.QRectF(left, top, width, height)

视图坐标：即窗口界面的物理坐标，单位是像素，其左上角为原点坐标，所有鼠标事件、拖拽事件最开始都使用视图坐标，
        为了和图元交互，需要转换坐标为场景坐标；
        
场景坐标：对应QPainter的逻辑坐标，以场景的中心为原点，X轴正方向向右，Y轴正方向向下.

图形项坐标：图元存在于自己的本地坐标上，通常以图元的中心为原点，图元中心也是所有坐标变换的原点，
        图元坐标方向是X轴正方向向右，Y轴正方向向下（同上图）。
'''

class Butterfly(QGraphicsItem):
    def __init__(self):
        super().__init__()
        self.im1 = QPixmap('./butterfly.png')
        self.im2 = QPixmap('./butterfly_down.png')
        self.up = True


        self.times = QTimer()
        self.times.start(500) #ms
        self.times.timeout.connect(self.transSPos)
        self.index_x = 0
        self.index_y = 0
        self.angle = 0

    def transSPos(self):

        #边界控制
        edgex = self.scene().sceneRect().right() + self.boundingRect().width() / 2
        edgetop = self.scene().sceneRect().top() + self.boundingRect().height() / 2
        edgebottom = self.scene().sceneRect().bottom() + self.boundingRect().height() / 2

        if (self.pos().x() >= edgex):
            print("This is edgex")
            print(edgex, edgetop, edgebottom)
            self.setPos(self.scene().sceneRect().left(), self.pos().y())
        if (self.pos().y() <= edgetop):
            print("This is edgetop")
            print(edgex, edgetop, edgebottom)
            self.setPos(self.pos().x(), self.scene().sceneRect().bottom())
        if (self.pos().y() >= edgebottom):
            print("This is edgebottom")
            print(edgex, edgetop, edgebottom)
            self.setPos(self.pos().x(), self.scene().sceneRect().top())
        #
        self.angle += (qrand() % 10) / 20.0
        self.index_x = math.fabs(math.sin(self.angle * math.pi) * 10.0)
        self.index_y = (qrand() % 20) - 10.0
        self.setPos(self.mapToParent(self.index_x, self.index_y))

        print(self.angle, self.index_x, self.index_y)
        print("映射到父类", self.mapToParent(self.index_x, self.index_y))
        print("边界矩形框：", self.boundingRect())
        print("场景位置: ", self.scene().sceneRect())
        print("当前位置：", self.pos())

    # 设定图片元的大小范围
    def boundingRect(self):
        adjust = 2 #调整大小的一个参数

        return QRectF(-self.im1.width()/2 - adjust, -self.im1.height() - adjust,
                      self.im1.width() + adjust*2, self.im1.width() + adjust*2)

    def paint(self, painter, option, widget):
        if self.up:
            print(self.boundingRect().topLeft())
            painter.drawPixmap(self.boundingRect().topLeft(), self.im1)
            self.up = not self.up
            print(self.up)
        else:
            print(self.boundingRect().topLeft())
            painter.drawPixmap(self.boundingRect().topLeft(), self.im2)
            self.up = not self.up
            print(self.up)

class MainWindows(QMainWindow):
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("飞舞的蝴蝶")
        self.setGeometry(300, 300, 500, 500)
        layout = QHBoxLayout()
        self.view = QGraphicsView()
        self.view.setMinimumSize(500, 500)
        self.sence = QGraphicsScene()

        self.butterfly = Butterfly()
        self.sence.addItem(self.butterfly)
        self.view.setScene(self.sence)
        layout.addWidget(self.view)
        self.setLayout(layout)
        self.setCentralWidget(self.view)

if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex_ = MainWindows()
    ex_.show()
    sys.exit(app.exec_())